package net.sf.rose.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import net.sf.rose.jdbc.ConstantCode;
import net.sf.rose.jdbc.PageBean;

/**
 * 类说明：数据设值取值封装类
 * 
 * @author fengjian E-mail: 9110530@qq.com
 * @version 创建时间：2016-10-20 上午10:28:34
 */
public class BeanWrapper {

	private static Logger LOG = Logger.getLogger(BeanWrapper.class);

	/** 多国语言类型 */
	private String languagePrefix = null;

	/** 数据对象 */
	private Object bean = null;

	/** 数据对象类型 */
	private Class<?> entity = null;

	/** 数据对象所有属性集合 */
	private Map<String, Field> AllFields = null;

	public BeanWrapper() {
		super();
	}

	public BeanWrapper(Object bean) {
		super();
		setWrappedInstance(bean);
	}

	/**
	 * 功能：设置要操作的对象
	 * 
	 * @param bean - 要操作的对象
	 */
	public void setWrappedInstance(Object bean) {
		this.bean = bean;
		if (this.entity == null) {
			this.setWrappedClass(bean.getClass());
		}
	}

	/**
	 * 功能：设置要操作的对象
	 * 
	 * @param clazz - 要操作的类
	 */
	public void setWrappedClass(Class<?> clazz) {
		AllFields = new HashMap<>();
		while (clazz != Object.class) {
			for (Field f : clazz.getDeclaredFields()) {
				if (!Modifier.isFinal(f.getModifiers())) {
					AllFields.put(f.getName(), f);
				}
			}
			clazz = clazz.getSuperclass();
		}
	}

	/**
	 * 设置语言 cn,en,jp
	 * 
	 * @param language - 语言类型
	 */
	public void setLanguage(String language) {
		this.languagePrefix = StringUtil.getLanguagePrefix(language);
	}

	/**
	 * 功能：设置对象指定的属性对应的值
	 * 
	 * @param key - 属性名称
	 * @param val - 值
	 * @return 设值是否成功
	 */
	public PageBean set(String key, Object val) {
		PageBean page = new PageBean();
		try {
			Field field = AllFields.get(key);
			if (field == null || val == null) {
				page.setSuccess(false);
				return page;
			}
			field.setAccessible(true);
			String ptype = field.getGenericType().getTypeName();// 属性类型
			String vtype = ConstantCode.getSimpleType(val.getClass().getName());// 数据典型
			// 如果数据类型与属性类型一致
			if (ptype.equals(vtype)) {
				field.set(bean, val);
				// 如果设置了语言，并且是字符串
				if (this.languagePrefix != null && vtype.equals("java.lang.String")) {
					// 如果字段名称是Name结尾
					String str = null;
					if (key.endsWith(this.languagePrefix + "Name")) {
						str = "Name";
					}
					// 如果字段名称是Text结尾
					else if (key.endsWith(this.languagePrefix + "Text")) {
						str = "Text";
					}
					if (str != null) {
						key = key.substring(0, key.length() - 5) + str;
						field = AllFields.get(key);
						if (field != null) {
							field.setAccessible(true);
							field.set(bean, val);
						}
					}
				}
			} else {
				// 如果属性的类型是数组
				if (field.getType().isArray()) {
					// 如果是字节流
					if (ptype.indexOf(ConstantCode.JAVA_TYPE_BYTE_ARRAY) != -1) {
						field.set(bean, val);
					} else {
						String string = val.toString();
						// 如果是以逗号分隔的字符串数组
						if (ptype.indexOf(ConstantCode.JAVA_TYPE_STRING) != -1) {
							String[] arr = StringUtils.split(string, ',');
							field.set(bean, arr);
						}
						// 如果是以逗号分隔的整数数组
						else if (ptype.indexOf(ConstantCode.JAVA_TYPE_INTEGER) != -1) {
							String[] s = StringUtils.split(string, ',');
							int[] arr = new int[s.length];
							for (int i = 0; i < s.length; i++) {
								arr[i] = Integer.parseInt(s[i]);
							}
							field.set(bean, arr);
						}
					}
				} else {
					field.set(bean, DataUtils.convertValue(ptype, val));
				}
			}
			return page;
		} catch (Exception e) {
			page.setSuccess(false);
			page.setMessage("key=" + key + ";value=" + val + ";message=" + e.getMessage());
			return page;
		}
	}

	/**
	 * 功能：查看对象是否含有某个属性
	 * 
	 * @param key - 属性名称
	 * @return 属性值
	 */
	public boolean has(String key) {
		Field field = AllFields.get(key);
		return field != null;
	}

	/**
	 * 功能：获取对象指定的字段值
	 * 
	 * @param key - 属性名称
	 * @return 属性值
	 */
	public Object get(String key) {
		try {
			Field field = AllFields.get(key);
			if (field == null) {
				return null;
			}
			field.setAccessible(true);
			return field.get(bean);
		} catch (Exception e) {
			LOG.warn(e.getMessage(), e);
			return null;
		}
	}

	/**
	 * 功能：获取对象对应的所有属性集
	 * 
	 * @return 对象对应的所有属性集
	 */
	public Map<String, Field> getAllFields() {
		return AllFields;
	}

	/**
	 * 功能：获取所有属性名称
	 * 
	 * @return 所有属性名称
	 */
	public String[] getAllFieldNames() {
		int i = 0;
		String[] arr = new String[AllFields.size()];
		for (String s : AllFields.keySet()) {
			arr[i] = s;
			i++;
		}
		return arr;
	}
}
